package team.hyznrj.studentsys.utils;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

import team.hyznrj.studentsys.exception.AuthenticationOnFlagException;
import team.hyznrj.studentsys.exception.DataIllegalException;
import team.hyznrj.studentsys.exception.DataNullException;

public class ValueUtil<T> {
	private static final char PATTERN_CHAR = 'A';
	private static final String PATTERN_THREE_CHAR = "AAA";

	public static boolean findFile(String path){
		File file=new File(path);
		return file.exists();
	}
	public static String codeUrl(String str, String flag) throws UnsupportedEncodingException {
		String path = AESUtil.encrypt(str, ValueUtil.getFlag(flag, 1));
		System.out.println("code:" + path);
		StringBuffer sbf = new StringBuffer();
		if (!StringUtils.isEmpty(path)) {
			for (int i = 0; i < path.length(); i++) {
				char charAt = path.charAt(i);
				if (charAt == PATTERN_CHAR) {
					sbf.append(PATTERN_THREE_CHAR);
				} else if (!String.valueOf(charAt).matches("[0-9A-Za-z]")) {
					sbf.append(PATTERN_CHAR);
					sbf.append((int) charAt);
					sbf.append(PATTERN_CHAR);
				} else {
					sbf.append(charAt);
				}
			}
		}
		return sbf.toString();
	}

	public static String encodeUrl(String str, String flag) throws UnsupportedEncodingException {
		String path = str;
		// URLDecoder.decode(path,"utf-8");
		StringBuffer sbf = new StringBuffer();
		if (!StringUtils.isEmpty(path)) {
			int count = 0;
			while (count < path.length()) {
				char charAt = path.charAt(count);
				if (charAt == PATTERN_CHAR) {
					if (count + 2 < path.length() && path.charAt(count + 1) == PATTERN_CHAR
							&& path.charAt(count + 2) == PATTERN_CHAR) {
						// 如果满足转义字符开始结束，则直接跳过并追加转义字符
						sbf.append(PATTERN_CHAR);
						count += 3;
					} else {
						int off = count + 1;
						StringBuffer tmp = new StringBuffer();
						while (path.charAt(off) != PATTERN_CHAR) {
							tmp.append(path.charAt(off));
							off++;
							if (off >= path.length()) {
								throw new DataIllegalException("下载页面未存在{reason:offset<length}");
							}
						}
						if (tmp.length() > 0) {
							try {
								int valueOf = Integer.valueOf(tmp.toString());
								sbf.append((char) valueOf);
							} catch (Exception e) {
								e.printStackTrace();
								throw new DataIllegalException("下载页面未存在{reason:throw Exception}");
							}

						} else {
							throw new DataIllegalException("下载页面未存在{reason:length<=0}");
						}
						count = off + 1;
					}
				} else {
					sbf.append(charAt);
					count++;
				}
			}
		}
		try {
			path = AESUtil.decrypt(sbf.toString(), ValueUtil.getFlag(flag, 1));
		} catch (Exception e) {
			e.printStackTrace();
			throw new AuthenticationOnFlagException();
		}
		return path;
	}

	public static boolean isDecimal(String str) {
		if (StringUtils.isEmpty(str)) {
			return false;
		}
		return str.matches("-?[0-9]+.?[0-9]+");
	}

	/**
	 * 获取四舍五入
	 * @param number
	 * @return
	 */
	public static int getIntByDouble(double number,boolean rounding) {
		if(!rounding){
			return (int)number;
		}
		if (number >= ((int) number + 0.5)) {
			return (int) number + 1;
		} else {
			return (int) number;
		}
	}

	public static int getBiggerInteger(int a, int b) {
		return a > b ? a : b;
	}

	/**
	 * 对跳动数组进行排序 如: 99,77,66,88 会变成 3,1,0,2
	 * 
	 * @param list
	 * @return
	 */
	public static List<Integer> getIntegerListByCount(List<Integer> list) {
		if (list != null && list.size() > 0) {
			List<Integer> result = new ArrayList<>();
			List<Integer> tmp = new ArrayList<>();
			for (Integer str : list) {
				tmp.add(str);
			}
			sortInteger(tmp);
			for (int i = 0; i < list.size(); i++) {
				Integer v1 = list.get(i);
				for (int j = 0; j < tmp.size(); j++) {
					if (tmp.get(j) == v1) {
						result.add(j);
						break;
					}
				}
			}
			return result;
		}
		return null;
	}

	/**
	 * 由小到大对INTEGER数组进行排序
	 * 
	 * @param list
	 * @return
	 */
	public static List<Integer> sortInteger(List<Integer> list) {
		list.sort(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				if (o1 == o2) {
					return 0;
				}
				if (o1 > o2) {
					return 1;
				} else {
					return -1;
				}
			}
		});
		return list;
	}

	/**
	 * 保持数字大于等于0
	 * 
	 * @param number
	 * @return
	 */
	public static int noZero(Integer number) {
		if (number == null || number <= 0) {
			return 0;
		} else {
			return number;
		}
	}

	/**
	 * 对数组进行排序 从小到大 长度低的在前 长度一样的则比较 值的大小
	 */
	public static List<String> sort(List<String> list) {
		if (list != null) {
			for (int i = 0; i < list.size(); i++) {
				String str = list.get(i);
				int swap = -1;
				for (int j = i + 1; j < list.size(); j++) {
					String tmp = list.get(j);
					if (str.length() > tmp.length() || (str.length() == tmp.length() && str.compareTo(tmp) > 0)) {
						swap = j;
					}
				}
				if (swap != -1) {
					list.set(i, list.get(swap));
					list.set(swap, str);
				}
			}
		}
		return list;
	}

	public static Map<Double, Integer> sortOrder(List<Double> courseGradeList) {
		return DoubleSort.getOrder(courseGradeList);
	}

	/**
	 * 预处理字符填充
	 * 
	 * @param str
	 * @param c
	 * @param params
	 * @return
	 */
	public static String getString(final String str, final char c, final Object... params) {
		StringBuffer sbf = new StringBuffer();
		int count = 0;
		for (int i = 0; i < str.length() && count < params.length; i++) {
			char charAt = str.charAt(i);
			if (c == charAt) {
				sbf.append(params[count]);
				count++;
			} else {
				sbf.append(charAt);
			}
		}
		return sbf.toString();
	}

	/**
	 * 用splitChar的每个值分割字符串key
	 * 
	 * @param key
	 * @param splitChar
	 * @return
	 */
	public static List<String> splitKey(final String key, final String splitChar) {
		List<String> list = new ArrayList<>();
		StringBuffer sbf = new StringBuffer();
		boolean flag = false;
		for (int i = 0; i < key.length(); i++) {
			char charAt = key.charAt(i);
			flag = false;
			for (int j = 0; j < splitChar.length(); j++) {
				if (charAt == splitChar.charAt(j)) {
					if (sbf.length() > 0) {
						list.add(sbf.toString());
					}
					sbf.setLength(0);
					flag = true;
					break;
				}
			}
			if (!flag) {
				sbf.append(charAt);
			}
		}
		if (sbf.length() > 0) {
			list.add(sbf.toString());
		}
		return list;
	}

	public static String noneEmpty(final String value, final String defaul, final boolean throwExceptionAble) {
		boolean flag = StringUtils.isEmpty(value);
		if (throwExceptionAble && flag) {
			throw new DataNullException();
		}
		return flag ? defaul : value;
	}

	/**
	 * 1：学院 2：系 3：用户
	 * 
	 * @param flag
	 * @param level
	 * @return
	 */
	public static String getFlag(final String flag, final int level) {
		if (1 == level) {
			return getIndexFromFlag(flag, 0);
		}
		if (2 == level) {
			return getIndexFromFlag(flag, 0, 1);
		}
		if (3 == level) {
			return getIndexFromFlag(flag, 0, 1, 2);
		}
		throw new DataNullException("Level非法");
	}

	/**
	 * 
	 * @param value
	 * @param code
	 *            -1:左匹配 0:全匹配 1:右匹配 2:任意匹配
	 * @return
	 */
	public static Pattern getRegexPattern(String value, int code) {
		StringBuffer sbf = new StringBuffer();
		if (code == 1) {
			sbf.append("^.*" + value + "$");
		} else if (code == -1) {
			sbf.append("^" + value + ".*$");
		} else if (code == 0) {
			sbf.append("^.*" + value + ".*$");
		} else if (code == 2) {
			sbf.append("^" + value.replaceAll("", ".*") + "$");
		}
		return Pattern.compile(sbf.toString(), Pattern.CASE_INSENSITIVE);

	}

	/**
	 * 检测map有效性 getMap
	 * 
	 * @param map
	 * @param setEmpty
	 *            为true时，将null值设置为""，否则则移除
	 * @return
	 * @return Map<Object,Object>
	 */
	public Map<T, String> getMap(Map<T, String> map, boolean setEmpty) {
		Set<T> keySet = map.keySet();
		for (T key : keySet) {
			String value = map.get(key);
			if (value == null) {
				if (setEmpty) {
					map.replace(key, value, "");
				} else {
					map.remove(key, value);
				}
			}
		}
		return map;
	}

	/**
	 * 获取唯一标志
	 */
	public static String getIndexFromFlag(String flag, int... index)
			throws DataNullException, AuthenticationOnFlagException {
		// String[] split = flag.split("#");
		if (flag == null) {
			throw new AuthenticationOnFlagException();
		}
		/* 重写split操作 */
		ArrayList<String> split = new ArrayList<>();
		int count = 0;
		StringBuffer sb = new StringBuffer();
		while (count < flag.length()) {
			char charAt = flag.charAt(count);
			if (charAt != '#') {
				sb.append(charAt);
			} else {
				if (sb.length() > 0) {
					split.add(sb.toString());
					sb.setLength(0);
				} else {
					split.add("");
				}
			}
			count++;
		}
		if (sb.length() > 0) {
			split.add(sb.toString());
		} else {
			split.add("");
		}
		/* 功能实现 */
		StringBuffer sbf = new StringBuffer();
		for (int i = 0; i < index.length; i++) {
			if (split.size() - 1 < index[i] || split.get(index[i]) == null) {
				throw new AuthenticationOnFlagException();
			} else {
				sbf.append(split.get(index[i]));
				sbf.append("#");
			}
		}
		sbf.deleteCharAt(sbf.length() - 1);
		return sbf.toString();
	}
}

class DoubleSort {
	/**
	 * 从大到小排序并获得排序后的排名映射 从1开始
	 * 
	 * @param courseGradeList
	 * @return
	 */
	public static Map<Double, Integer> getOrder(List<Double> courseGradeList) {
		Map<Double, Integer> map = new HashMap<>();
		/**
		 * 从大到小排序
		 */
		courseGradeList.sort(new Comparator<Double>() {
			@Override
			public int compare(Double o1, Double o2) {
				if (o1 == null || o2 == null) {
					return 1;
				}
				if (o1 > o2) {
					return -1;
				}
				if (o1 < o2) {
					return 1;
				}
				return 0;
			}
		});
		for (int i = 0; i < courseGradeList.size(); i++) {
			if (map.containsKey(courseGradeList.get(i))) {
				continue;
			}
			map.put(courseGradeList.get(i), i + 1);
		}
		return map;
	}
}
